import wx
import math 
from log_object import *

def makeNew(parent, window, param1):
    """ this is how we instantiate the device object from
        the main program that loads this plugin """
    return WindowGraph(parent, window, param1)

class WindowGraph:
	def __init__(self, parent, window, param1):
		self.parent = parent
		self.window = window

		self.type = WINDOWGRAPH
		self.param1 = param1
		self.param2 = NOT_DEFINED 

		self.log_date = ""
		self.start = 0
		self.end = 0 
		self.panel_end = 0 
		self.dim = [] 
		self.space = [] 

	def draw(self, dc, start, end, dim, space):
		foreground = self.parent.getForegroundColor()
		background = self.parent.getBackgroundColor()

		self.start = start
		self.end = end 
		self.panel_end =  end 
		self.dim = dim
		self.space = space

		dc.SetBrush(wx.TRANSPARENT_BRUSH)
		dc.SetPen(wx.Pen(foreground, 1))
		dc.SetTextBackground(background)
		dc.SetTextForeground(foreground)
		font = wx.Font(15, wx.TELETYPE, wx.NORMAL, wx.BOLD)
		dc.SetFont(font)

		base_unit = 10
		window_width = int(self.window.Width / space[0])
		window_height = int(self.window.Height / space[1])

		# 1. draw vertical line & information
		x = (dim[0] * window_width) + 30
		origin_x = x
		y = (dim[1] * window_height) + window_height -61
		dc.DrawLines(((x, dim[1] * window_height), (x, y)))
		right_gap = 50
		graph_width = window_width - right_gap 
		endx = (dim[0] * window_width) + graph_width 
 		y_start = dim[1] * window_height 
		if self.param1 == LOG_WINDOW_DIS_SIZE:
			dc.DrawText("space percentage %", window_width-170, y+30)
			dc.DrawText("number of window", x +10, y_start+15)
		elif self.param1 == LOG_WINDOW_DIS_TIME:
			dc.DrawText("time percentage %", window_width-170, y+30)
			dc.DrawText("number of window", x +10, y_start+15)
		else : 
			dc.DrawText("window", window_width-70, y+30)

		dc.SetPen(wx.Pen(foreground, 1))
		no_logs = len(self.parent.log_list)
		y = y_start + window_height -61
		each_height = window_height -61 
		if no_logs > 0 : 
			each_height = (window_height - 61) / no_logs 
			y = y_start  
		else :
			dc.DrawLines(((x, y), (endx+right_gap, y)))

		if self.param1 == LOG_WINDOW_LIFETIME:
			dc.DrawText("WINDOW AVERAGE LIFE TIME", x+10, y_start)
		elif self.param1 == LOG_WINDOW_CHANGE:
			dc.DrawText("WINDOW CHANGE", x+10, y_start)
		elif self.param1 == LOG_WINDOW_SIZE:
			dc.DrawText("WINDOW AVERAGE SIZE", x+10, y_start)
		elif self.param1 == LOG_WINDOW_DIS_SIZE:
			dc.DrawText("WINDOW AVERAGE SIZE DISTRIBUTION", x+10, y_start)
		else :
			dc.DrawText("WINDOW AVERAGE LIFE TIME DISTRIBUTION", x+10, y_start)

		x1 = (dim[0] * window_width) + graph_width - 120
		y1 = y
		for log in self.parent.log_list :
			y1 += each_height 
			dc.DrawLines(((x, y1), (endx+right_gap, y1)))
			dc.DrawText(log.date, x1, y1 - each_height + 10)

		font = wx.Font(12, wx.TELETYPE, wx.NORMAL, wx.BOLD)
		dc.SetFont(font)
		y1 = y
		for log in self.parent.log_list :
			y1 += each_height 
			dc.DrawText("-duration: " + str(log.duration) + " min", x1, y1 - each_height + 30)
			no_x = len(log.window_list)
			dc.DrawText("-no of windows: " + str(no_x), x1, y1 - each_height + 45)

		max_no_windows = 0
		for current_log in self.parent.log_list :
			no_x = len(current_log.window_list)
			if no_x > max_no_windows :
				max_no_windows = no_x
		unit_x = int(1.0 * graph_width / max_no_windows)

		if self.param1 == LOG_WINDOW_LIFETIME:
			self.drawLifeTime(dc, x, y, graph_width, each_height, unit_x)
		elif self.param1 == LOG_WINDOW_SIZE:
			self.drawSize(dc, x, y, graph_width, each_height, unit_x)
		elif self.param1 == LOG_WINDOW_CHANGE:
			self.drawChanges(dc, x, y_start, graph_width, each_height, unit_x)
		elif self.param1 == LOG_WINDOW_DIS_SIZE:
			unit_x = int(1.0 * graph_width / 10)
			self.drawSizeCurved(dc, x, y, graph_width, each_height, unit_x)
		else :
			self.drawLifeTimeCurved(dc, x, y, graph_width, each_height, unit_x)


	def drawLifeTime(self, dc, x, y, graph_width, each_height, unit_x):
		foreground = self.parent.getForegroundColor()
		background = self.parent.getBackgroundColor()

		for current_log in self.parent.log_list :
			log_end = current_log.duration * 60

			max_lifetime = 0
			min_lifetime = 999 
			ave_lifetime = 0.0
			for window in current_log.window_list: 
				ave_lifetime += (window.lifetime / log_end)
				if window.lifetime > max_lifetime :
					max_lifetime = window.lifetime 
				if window.lifetime < min_lifetime :
					min_lifetime = window.lifetime 
			ave_lifetime /= len(current_log.window_list)

			# calculate SD 
			sd = 0.0
			for window in current_log.window_list: 
				diff = (window.lifetime / log_end) - ave_lifetime 
				sd += (diff * diff)
			sd /= len(current_log.window_list)
			sd = math.sqrt(sd)

			dc.SetPen(wx.Pen(foreground, 1, style=wx.DOT))
			y1 = y + each_height - int(ave_lifetime * each_height)  
			dc.DrawLines(((x-50, y1),  (x+graph_width+50, y1)))
			y1 = y + each_height - int(max_lifetime / log_end * each_height)  
			dc.DrawLines(((x-50, y1),  (x+graph_width+50, y1)))

			ave_lifetime = ave_lifetime * 100
			sd = sd * 100
			max_lifetime = int(max_lifetime / 60)
			max_t = max_lifetime % 60
			min_lifetime = int(min_lifetime / 60)
			min_t = min_lifetime % 60
			dc.DrawText("ave=" + str(ave_lifetime) + "%, sd=" + str(sd) + ", max=" + str(max_lifetime) + "min " + str(max_t) + "sec, min=" + str(min_lifetime) + "min " + str(min_t) + "sec", x+ 10, y1-20)

			color = self.parent.getColor(3)
			dc.SetPen(wx.Pen(color, 1))
			dc.SetBrush(wx.Brush(color))
			x1 = x 
			y1 = y + each_height
			i = 0
			for window in current_log.window_list: 
				'''
				if i == 15 : 
					color = self.parent.getColor(2)
					dc.SetPen(wx.Pen(color, 1))
					dc.SetBrush(wx.Brush(color))
				elif i == 37 : 
					color = self.parent.getColor(4)
					dc.SetPen(wx.Pen(color, 1))
					dc.SetBrush(wx.Brush(color))
				'''
				h = int(window.lifetime / log_end * each_height)  
				dc.DrawRectangle(x1, y1-h, unit_x, h)
				x1 += unit_x
				i += 1

			dc.SetPen(wx.Pen(foreground, 1))
			x1 = x 
			for window in current_log.window_list: 
				dc.DrawLines(((x1, y1-5),  (x1, y1+5)))
				x1 += unit_x

			y += each_height 


	def drawSize(self, dc, x, y, graph_width, each_height, unit_x):
		foreground = self.parent.getForegroundColor()
		background = self.parent.getBackgroundColor()

		for current_log in self.parent.log_list :
			max_size = 0
			min_size = 999 
			ave_size = 0.0
			for window in current_log.window_list: 
				ave_size += window.ave_size
				if window.ave_size > max_size :
					max_size = window.ave_size
				if window.ave_size < min_size :
					min_size = window.ave_size
			ave_size /= len(current_log.window_list)

			# calculate SD 
			sd = 0.0
			for window in current_log.window_list: 
				diff = (window.ave_size - ave_size) 
				sd += (diff * diff)
			sd /= len(current_log.window_list)
			sd = math.sqrt(sd)

			dc.SetPen(wx.Pen(foreground, 1, style=wx.DOT))
			y1 = y + each_height - int(ave_size * each_height)  
			dc.DrawLines(((x-50, y1),  (x+graph_width+50, y1)))
			y1 = y + each_height - int(max_size * each_height)  
			dc.DrawLines(((x-50, y1),  (x+graph_width+50, y1)))

			ave_size = ave_size * 100
			max_size = max_size * 100
			min_size = min_size * 100 
			sd =sd * 100
			dc.DrawText("ave=" + str(ave_size) + "%, sd=" + str(sd) + ", max=" + str(max_size) + "%, min=" + str(min_size) + "%", x+ 10, y1-20)

			color = self.parent.getColor(3)
			dc.SetPen(wx.Pen(color, 1))
			dc.SetBrush(wx.Brush(color))
			x1 = x 
			y1 = y + each_height
			i = 0
			for window in current_log.window_list: 
				'''
				if i == 15 : 
					color = self.parent.getColor(2)
					dc.SetPen(wx.Pen(color, 1))
					dc.SetBrush(wx.Brush(color))
				elif i == 37 :
					color = self.parent.getColor(4)
					dc.SetPen(wx.Pen(color, 1))
					dc.SetBrush(wx.Brush(color))
				'''
				
				h = int(window.ave_size * each_height)  
				dc.DrawRectangle(x1, y1-h, unit_x, h)
				x1 += unit_x
				i += 1

			dc.SetPen(wx.Pen(foreground, 1))
			x1 = x 
			for window in current_log.window_list: 
				dc.DrawLines(((x1, y1-5),  (x1, y1+5)))
				x1 += unit_x

			y += each_height 


	def drawChanges(self, dc, x, y, graph_width, each_height, unit_x):
		foreground = self.parent.getForegroundColor()
		background = self.parent.getBackgroundColor()

		y = y + 40 
		each_height -=  40
		for current_log in self.parent.log_list :
			max_change = 0
			min_change = 999 
			ave_change = 0.0
			for window in current_log.window_list: 
				if window.no_change > max_change :
					max_change = window.no_change
				if window.no_change < min_change :
					min_change = window.no_change
				ave_change += window.no_change
			ave_change /= len(current_log.window_list)
			# calculate SD 
			sd = 0.0
			for window in current_log.window_list: 
				diff = (window.no_change - ave_change) 
				sd += (diff * diff)
			sd /= len(current_log.window_list)
			sd = math.sqrt(sd)

			dc.SetPen(wx.Pen(foreground, 1, style=wx.DOT))
			y1 = y + each_height - int(1.0 * ave_change / max_change * each_height)  
			dc.DrawLines(((x-50, y1),  (x+graph_width+50, y1)))
			dc.DrawLines(((x-50, y),  (x+graph_width+50, y)))

			dc.DrawText("ave=" + str(ave_change) + ", sd=" + str(sd) + ", max=" + str(max_change) + ", min=" + str(min_change) + "", x+ 10, y-20)

			color = self.parent.getColor(3)
			dc.SetPen(wx.Pen(color, 1))
			dc.SetBrush(wx.Brush(color))
			x1 = x 
			y1 = y + each_height
			i = 0
			for window in current_log.window_list: 
				#'''
				if i == 15 : 
					color = self.parent.getColor(2)
					dc.SetPen(wx.Pen(color, 1))
					dc.SetBrush(wx.Brush(color))
				elif i == 37 : 
					color = self.parent.getColor(4)
					dc.SetPen(wx.Pen(color, 1))
					dc.SetBrush(wx.Brush(color))
				#'''
				h = int(1.0 * window.no_change / max_change * each_height)  
				dc.DrawRectangle(x1, y1-h, unit_x, h)
				x1 += unit_x
				i += 1	

			dc.SetPen(wx.Pen(foreground, 1))
			x1 = x 
			for window in current_log.window_list: 
				dc.DrawLines(((x1, y1-5),  (x1, y1+5)))
				x1 += unit_x

			y += each_height 


	def drawSizeCurved(self, dc, x, y, graph_width, each_height, unit_x):
		foreground = self.parent.getForegroundColor()
		background = self.parent.getBackgroundColor()

		ave_size_data = []
		for i in range(10) : 
			ave_size_data.append(0)

		max = 0
		for current_log in self.parent.log_list :
			for window in current_log.window_list: 
				i = int(window.ave_size * 100) / 10
				ave_size_data[i] += 1
				if ave_size_data[i] > max : 
					max = ave_size_data[i]

			dc.SetPen(wx.Pen(foreground, 1, style=wx.DOT))
			y1 = y + each_height
			x1 = x
			for i in range(10) :
				x1 += unit_x
				dc.DrawLines(((x1, y1),  (x1, 50)))
				dc.DrawText(str((i+1)*10), x1-5, y1+5)

			unit_y = 1.0 * (each_height - 50) / max
			y1 = y + each_height - int(max * unit_y)  
			dc.DrawLines(((x-50, y1),  (x+graph_width+50, y1)))

			color = self.parent.getColor(3)
			dc.SetPen(wx.Pen(color, 1))
			dc.SetBrush(wx.Brush(color))
			x1 = x 
			y1 = y + each_height
			half_x_unit = unit_x / 2
			for w in ave_size_data:
				h = int(w * unit_y)  
				dc.DrawRectangle(x1, y1-h, unit_x, h)
				dc.DrawText(str(w), x1+half_x_unit, y1-h-15)
				x1 += unit_x
			y += each_height 

		del ave_size_data


	def drawLifeTimeCurved(self, dc, x, y, graph_width, each_height, unit_x):
		foreground = self.parent.getForegroundColor()
		background = self.parent.getBackgroundColor()

		ave_time_data = []
		for i in range(100) : 
			ave_time_data.append(0)

		max = 0
		max_i = 0
		for current_log in self.parent.log_list :
			log_end = current_log.duration * 60

			for window in current_log.window_list: 
				T = (window.lifetime / log_end)
				i = int(T * 100) 
				ave_time_data[i] += 1
				if ave_time_data[i] > max : 
					max = ave_time_data[i]
				#print window.lifetime, log_end, i
				if i > max_i :
					max_i = i
					#print max_i, ave_time_data[i] 

			max_i += 1
			unit_x = int(1.0 * graph_width / max_i)
			dc.SetPen(wx.Pen(foreground, 1, style=wx.DOT))
			y1 = y + each_height
			x1 = x
			for i in range(max_i) :
				x1 += unit_x
				dc.DrawLines(((x1, y1),  (x1, 50)))
				dc.DrawText(str(i+1), x1-5, y1+5)

			unit_y = 1.0 * (each_height - 50) / max
			y1 = y + each_height - int(max * unit_y)  
			dc.DrawLines(((x-50, y1),  (x+graph_width+50, y1)))

			color = self.parent.getColor(3)
			dc.SetPen(wx.Pen(color, 1))
			dc.SetBrush(wx.Brush(color))
			x1 = x 
			y1 = y + each_height
			half_x_unit = unit_x / 2
			for i in range(max_i) :
				w = ave_time_data[i]
				h = int(w * unit_y)  
				dc.DrawRectangle(x1, y1-h, unit_x, h)
				dc.DrawText(str(w), x1+half_x_unit, y1-h-15)
				x1 += unit_x
			y += each_height 

		del ave_time_data

